"""
Copyright (c) 2022 Huawei Technologies Co.,Ltd.

openGauss is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:

          http://license.coscl.org.cn/MulanPSL2

THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
"""
"""
Case Type   : 故障&可靠性测试
Case Name   : 夏令时切换
Create At   : 2020/10/12
Owner       : @peilinqian
Description :
    1、设置操作系统时区为new_york
    2、设置操作系统时间为2020-03-08凌晨01:58
    3、等待2分钟后，夏令时开始。查看数据库数据时间是否是夏令时时间
    4、执行TPCC
Expect      :
    1、操作系统时区设置成功
    2、操作系统时间设置成功
    3、数据库新插入数据时间为夏令时时间
    4、TPCC运行成功
History     :
    modified: 2021/01/08  modified by @peilinqian,增加TPCC，保证夏令时跳转后业务可正常运行
    modified: 2021/01/20  modified by @peilinqian,调整修改时区和时间的顺序
    modified：2021/03/03  modified by @peilinqian，修改整个用例，增加必要打印信息
    Modified by @peilinqian 2021/3/23: 增加环境时区修复步骤
"""
import datetime
import os
import time
import unittest

from testcase.utils.Common import Common
from testcase.utils.CommonSH import *
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger
from yat.test import Node
from yat.test import macro

new_york_local = '/usr/share/zoneinfo/America/New_York'
ln_sf_cmd = 'ln -sf {zone} /etc/localtime'


class ModifyConnection(unittest.TestCase):
    nodes_tuple = ('PrimaryDbUser', 'Standby1DbUser', 'Standby2DbUser')

    @RestartDbCluster(*nodes_tuple)
    def setUp(self):
        self.log = Logger()
        self.log.info("----this is setup----")
        self.pri_dbuser = Node(node='PrimaryDbUser')
        self.pri_root = Node(node='PrimaryRoot')
        self.common = Common()
        self.pri_sh = CommonSH('PrimaryDbUser')
        self.constant = Constant()
        self.log.info("----Opengauss_Reliability_OS_Case007 start----")

        result = self.common.check_system_timezone(
            *('PrimaryRoot', 'Standby1Root', 'Standby2Root'))
        self.log.info(result)
        self.assertTrue(result)

        initial_time_cmd = 'date \'+%Y-%m-%d %H:%M:%S\''
        self.initial_time = self.pri_root.sh(initial_time_cmd).result()
        self.initial_zone = self.pri_root.sh('ls -l /etc/localtime').result()
        init_info = f'initial info: {self.initial_time}, {self.initial_zone}.'
        self.log.info(init_info)

    def test_modify_pidfile(self):
        self.log.info('----修改 postgresql.conf设置timezone----')
        self.initial_conf = os.path.join(macro.DB_INSTANCE_PATH,
                                         'postgresql.conf')
        self.new_conf = os.path.join(macro.DB_INSTANCE_PATH,
                                     'postgresql.conf.new')
        set_timezone_cmd = f"cp {self.initial_conf} {self.new_conf}; " \
            f"echo 'timezone=America/New_York' >> {self.initial_conf}"
        self.log.info(set_timezone_cmd)
        self.pri_dbuser.sh(set_timezone_cmd)

        self.log.info('----重载配置文件使配置文件生效----')
        result = self.pri_sh.reloadDbConfig()
        self.assertIn(self.constant.RELOAD_SUCCESS_MSG, result)

        self.log.info('----设置主节点时区为纽约----')
        set_sys_timezone = ln_sf_cmd.format(zone=new_york_local)
        self.log.info(set_sys_timezone)
        set_result = self.pri_root.sh(set_sys_timezone).result()
        self.log.info(set_result)
        self.log.info('----设置操作系统时间:03/08/2020 01:59:50(3月第二个周日，即将开始夏令时)----')
        datecmd = "date -s '03/08/2020 01:59:50';hwclock --systohc ;" \
                  "service ntpd stop;ntpdate ntp.api.bz;service ntpd start"
        self.log.info(self.pri_root.sh(datecmd).result())
        self.log.info(self.pri_root.sh('date').result())

        self.log.info('----查看当前时区----')
        result = self.pri_root.sh('ls -l /etc/localtime;date').result()
        self.log.info(result)
        self.log.info('----查看当前数据库系统时间----')
        before_time = self.pri_sh.executDbSql('select now();show timezone;')
        self.log.info(before_time)
        self.assertIn('2020-03-08', before_time)

        self.log.info("----执行tpcc----")
        cmd = f"rm -rf " \
            f"{os.path.join(macro.TPCC_PATH, 'my_result_2020-03-08')}_*"
        self.log.info(cmd)
        self.log.info(self.pri_root.sh(cmd).result())
        tpcc_result = self.common.startTPCC(self.pri_root, macro.TPCC_PATH)
        self.log.info(tpcc_result)
        self.assertIn(self.constant.TPCC_SUCCESS_MSG, tpcc_result)

        self.log.info('----查看当前时区----')
        result = self.pri_root.sh('ls -l /etc/localtime;date').result()
        self.log.info(result)
        self.log.info('----查看当前数据库系统时间----')
        before_time = self.pri_sh.executDbSql('select now();show timezone;')
        self.log.info(before_time)
        self.assertTrue(before_time.find("2020-03-08 03:") > -1)

    def tearDown(self):
        self.log.info('----this is tearDown----')
        self.log.info('----恢复数据库时区设置----')
        cmd = f'mv {self.new_conf} {self.initial_conf};'
        self.pri_dbuser.sh(cmd)
        result = self.pri_sh.reloadDbConfig()
        self.log.info(result)

        self.log.info('----恢复操作系统时区设置----')
        result = self.pri_root.sh('ls -l /etc/localtime').result()
        self.log.info(result)
        recover_timezone = self.initial_zone.split('->')[1]
        self.log.info(recover_timezone)
        recovery_zone_cmd = ln_sf_cmd.format(zone=recover_timezone)
        self.log.info('recover: ' + recovery_zone_cmd)
        self.pri_root.sh(recovery_zone_cmd)
        self.log.info('----查看当前时区----')
        result = self.pri_root.sh('ls -l /etc/localtime').result()
        self.log.info(result)

        self.log.info('----恢复操作系统时间----')
        current_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        date_cmd = f'date -s \'{current_time}\''
        self.log.info('recover: ' + date_cmd)
        self.log.info(self.pri_root.sh(date_cmd).result())
        self.log.info(self.pri_root.sh('date').result())

        self.log.info('----查看当前数据库系统时间----')
        current_time = self.pri_sh.executDbSql('select now();show timezone;')
        self.log.info(current_time)
